/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MAIN;

/**
 *
 * @author anhdung
 */
import DAO.Connect;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.KeyFactory;
import java.security.spec.InvalidKeySpecException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.*;
import java.io.*;
import java.math.BigInteger;
import java.security.Key;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;

public class GeneratePublicPrivateKeys {
    
    public void generateKeys() {

        try {

            // Get the public/private key pair
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(1024);
            KeyPair keyPair = keyGen.genKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey  publicKey  = keyPair.getPublic();

            // Get the bytes of the public and private keys
            byte[] privateKeyBytes = privateKey.getEncoded();
            byte[] publicKeyBytes  = publicKey.getEncoded();
			
            //converting byte arrays to strings
            String privateString = new String(privateKeyBytes);
            String publicString = new String(publicKeyBytes);
						
            KeyFactory fact = KeyFactory.getInstance("RSA");
            RSAPublicKeySpec pub = fact.getKeySpec(keyPair.getPublic(),RSAPublicKeySpec.class);
            RSAPrivateKeySpec priv = fact.getKeySpec(keyPair.getPrivate(),RSAPrivateKeySpec.class);

            saveToFile("public.key", pub.getModulus(), pub.getPublicExponent());
            saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent());

        } catch (InvalidKeySpecException specException) {

            System.out.println("Exception");
            System.out.println("Invalid Key Spec Exception");
            
        } catch (NoSuchAlgorithmException e) {

            System.out.println("Exception");
            System.out.println("No such algorithm: " + "RSA");

        }
		
		catch(IOException e) {
			System.out.println("IO exception");
		}	

    }
	
    private void saveToFile(String fileName,
      BigInteger mod, BigInteger exp) throws IOException {
      try (ObjectOutputStream oout = new ObjectOutputStream(
                 new BufferedOutputStream(new FileOutputStream(fileName)))) {
            oout.writeObject(mod);
            oout.writeObject(exp);
      } catch (Exception e) {
            throw new IOException("Unexpected error", e);
      }
    }
    
    public PublicKey readPubKeyFromFile(String keyFileName) throws IOException {
      FileInputStream in = new FileInputStream(keyFileName);
      ObjectInputStream oin =
            new ObjectInputStream(new BufferedInputStream(in));
      try {
            BigInteger m = (BigInteger) oin.readObject();
            BigInteger e = (BigInteger) oin.readObject();
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            PublicKey pubKey = fact.generatePublic(keySpec);
            return pubKey;
      } catch (Exception e) {
            throw new RuntimeException("Spurious serialisation error", e);
      } finally {
            oin.close();
      }
    }

    /* THis function implements the reading of the private key from the keyFileName*/
    public PrivateKey readPriKeyFromFile(String keyFileName) throws IOException {

      FileInputStream in = new FileInputStream(keyFileName);
      ObjectInputStream oin =
            new ObjectInputStream(new BufferedInputStream(in));
      try {
            BigInteger m = (BigInteger) oin.readObject();
            BigInteger e = (BigInteger) oin.readObject();
            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            PrivateKey priKey = fact.generatePrivate(keySpec);
            return priKey;
      } catch (Exception e) {
            throw new RuntimeException("Spurious serialisation error", e);
      } finally {
            oin.close();
      }
    }
    public byte[] encrypt(byte[] data) {
      try {
              PublicKey pubKey = readPubKeyFromFile("public.key");
              Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
              cipher.init(Cipher.ENCRYPT_MODE, pubKey);
              byte[] cipherData = cipher.doFinal(data);
              return cipherData;
       } catch(Exception e) { e.printStackTrace();return null;}

    }
    /*Decrypting here*/
    public byte[] decrypt(byte[] data) {
      try {
              PrivateKey priKey = readPriKeyFromFile("private.key");
              Cipher dcipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
              dcipher.init(Cipher.DECRYPT_MODE, priKey);
              byte[] cipherData = dcipher.doFinal(data);
              return cipherData;
            } catch(Exception e) { e.printStackTrace();return null;}

    }
    
    public static void main(String[] args) throws Exception
    {
        //tao public va private key
        GeneratePublicPrivateKeys gk = new GeneratePublicPrivateKeys();
        gk.generateKeys();
        PrivateKey privk = gk.readPriKeyFromFile("private.key");
        PublicKey pubk = gk.readPubKeyFromFile("public.key");
        System.out.println(privk);
        System.out.println(pubk);
        //Tiep theo, tao Cert tuong ung voi public key boi VeriSign
        usc_Certificate.privKey = privk;
        usc_Certificate.pubKey = pubk;
        usc_Certificate.createCertificate("SERVER.cer");
        //Nho VeriSign xem GUEST.cer co hop le
        usc_Certificate.validateCertificate("SERVER.cer");
        
        
        
    }
    
    
}


